package concurrent.chapter2;

import java.util.Optional;
import java.util.stream.IntStream;

/**
 * 1.所有的对象都会有一个wait set，用来存放调用了该对象wait方法之后进入block状态的线程
 * 2.线程被notify之后，不一定立即得到执行，要抢到锁再执行
 * 3.线程从wait set中被唤醒顺序不一定是FIFO先进先出
 * 4.线程被唤醒后，必须重新获取锁
 */
//同步语句块中有wait()时会释放锁，放弃cpu的执行权，进入block
//block到哪里了呢，总得有个地方存着，怎么去唤醒，唤醒后怎么继续执行
public class WaitSet {
    private static final Object LOCK = new Object();

    public static void main(String[] args) throws InterruptedException {
        IntStream.rangeClosed(1, 10)
                .forEach(i -> new Thread(String.valueOf(i)) {
                    @Override
                    public void run() {
                        synchronized (LOCK) {
                            try {
                                Optional.of(Thread.currentThread().getName() + " will come to wait.").ifPresent(System.out::println);
                                LOCK.wait();
                                //这个时候结束了wait的状态，变成了可执行状态，锁还没有释放
                                Optional.of(Thread.currentThread().getName() + " will leave to wait.").ifPresent(System.out::println);

                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }.start());

        Thread.sleep(3000);

        IntStream.rangeClosed(1, 10).forEach(i -> {
            synchronized (LOCK) {
                LOCK.notify();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
